package ee.serge.util;

import java.util.ArrayList;
import java.util.List;

import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Hyperlink;
import com.google.gwt.user.client.ui.Label;

import ee.serge.client.content.LoanDetailsContent;
import ee.serge.client.content.LoansRequester;
import ee.serge.shared.Loan;
import ee.serge.util.bootstrap.BTable;

public class Calculator extends FlowPanel {

   private SliderWithTextBox sumTextBox;
   private SliderWithTextBox periodTextBox;
   private List<Loan> filteredList;
   private FlowPanel tableHolder;
   private static int amount;
   private static int period;
   
   public Calculator(final boolean hasHeader) {
      if (LoansRequester.get().isLoading()) {
         LoansRequester.get().addValueChangeHandler(new ValueChangeHandler<List<Loan>>() {
            @Override
            public void onValueChange(ValueChangeEvent<List<Loan>> event) {
               buildForm(hasHeader);
            }
         });
      } else {
         buildForm(hasHeader);
      }
   }
   
   
   private void buildForm(boolean hasHeader) {
      if (hasHeader) {
         CalculateHandler handler = new CalculateHandler();
         FormPanel form = new FormPanel();
         form.add("Loan amount (£)", sumTextBox = new SliderWithTextBox((int)LoansRequester.get().getMinAmount(), (int)LoansRequester.get().getMaxAmount()));
         sumTextBox.addValueChangeHandler(handler);
         form.add("Loan period (days)", periodTextBox = new SliderWithTextBox((int)LoansRequester.get().getMinPeriod(), (int)LoansRequester.get().getMaxPeriod()));
         periodTextBox.addValueChangeHandler(handler);
         form.addStyleName("calculator");
         add(form);
      }
      
      add(tableHolder = new FlowPanel());
      
      if (period > 0 && amount > 0) {
         if (hasHeader) {
            sumTextBox.setValue(amount);
            periodTextBox.setValue(period);
         }
         buildTable(amount, period);
      }
   }
   
   private void calculateList(int amount, int period) {
      filteredList = new ArrayList<Loan>();
      for (Loan loan : LoansRequester.get().getLoans()) {
         if (loan.getMaxLoan() >= amount && loan.getMinLoan() <= amount && loan.getPeriod() >= period) {
            loan.setRepay(Math.round((amount + loan.getTransferFee()) * ((float)loan.getAnnualInterest() / 365) * ((float)period / 100) + loan.getTransferFee()));
            filteredList.add(loan);
         }
      }
      filteredList = bubbleSort(filteredList);
   }
   
   public static List<Loan> bubbleSort(List<Loan> loans){
      int n = loans.size();
      for (int pass = 1; pass < n; pass++) {
          for (int i = 0; i < n-pass; i++) {
              if (loans.get(i).getRepay() > loans.get(i+1).getRepay()) {
                  Loan temp = loans.get(i); 
                  loans.set(i, loans.get(i + 1));
                  loans.set(i + 1, temp);
              }
          }
      }
      return loans;
   }
   
   private void buildTable(int amount, int period) {
      
      calculateList(amount, period);
      
      String[] headers = {"#", "Name", "APR", "Interest", "Repay", "", ""};
      BTable table = new BTable(filteredList.size(), headers);
      table.addStyleName("calculator-table");
      for (int i = 0; i < filteredList.size(); i++) {
         Loan loan = filteredList.get(i);
         table.setText(i, 0, (i + 1) + ".");
         table.setText(i, 1, loan.getName());
         table.setText(i, 2, loan.getAPR() + "%");
         float interest = (amount + loan.getTransferFee()) * ((float)loan.getAnnualInterest() / 365) * ((float)period / 100) + loan.getTransferFee();
         table.setText(i, 3, "£" + Math.round(interest));
         table.setWidget(i, 4, Headers.h2("£" + Math.round(interest + amount)));
         table.setWidget(i, 5, new Hyperlink("Read more", LoanDetailsContent.getURLData(loan.getId()).getHref()));
         table.setWidget(i, 6,new Anchor("Appy now", loan.getLink()));
      }
      
      tableHolder.clear();
      Label label = new Label("Borrowing £" + amount + " for " + period + (period > 1 ? " days." : " day."));
      label.addStyleName("hx");
      tableHolder.add(label);
      tableHolder.add(table);
   }
   
   private class CalculateHandler implements ValueChangeHandler<Void> {

      @Override
      public void onValueChange(ValueChangeEvent<Void> event) {
         amount = Integer.valueOf(sumTextBox.getText());
         period = Integer.valueOf(periodTextBox.getText());
         buildTable(amount, period);
      }
      
   }
   
}
